package com.fingard.dsp.bank.directbank.zbf01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISMSRec;
import com.fingard.dsp.bank.reqrespobj.single.ReqQrySingle;
import com.fingard.dsp.bank.reqrespobj.single.RetAtsSingle;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.dsp.bank.reqrespobj.smsrec.ReqSMSRec;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;
import com.zhongbaofu.util.Util;

/**
 * @author XueJy on 2019/1/28.
 * @version 1.0
 */
public class ZBF01SMSRec extends ZBF01Base implements ISMSRec {

    @Override
    public RetAtsSingle d_9110_SMSRec(ReqSMSRec p_req9110) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req9110.reqHeader);
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
        tmpRetDetail.reqSeqID = p_req9110.singleDetail.askNumber;

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_req9110.singleDetail.recAct, "smsRec");
            if (actItem != null) {
                String mchId = actItem.merchantId;
                if ("01".equals(p_req9110.singleDetail.step)) {
                    /*签名及计算长度用xml*/
                    XmlTextWriter tmpXml = new XmlTextWriter();
                    /*发送银行用xml*/
                    XmlTextWriter xmlWriter = new XmlTextWriter();
                    writeCommonHeaderVer1(tmpXml, p_req9110.singleDetail.askNumber);
                    writeCommonHeaderVer1(xmlWriter, p_req9110.singleDetail.askNumber);
                    /*业务代码*/
                    tmpXml.writeElementString("BUSINCODE", ZBF01TransType.SMSSTEP1);
                    xmlWriter.writeElementString("BUSINCODE", ZBF01TransType.SMSSTEP1);
                    /*商户号*/

                    tmpXml.writeElementString("MERCHANTID", mchId);
                    xmlWriter.writeElementString("MERCHANTID", mchId);
                    /*支付号*/
                    tmpXml.writeElementString("POLICYID", "");
                    xmlWriter.writeElementString("POLICYID", "");
                    /*订单号 中保付生产的唯一编号*/
                    //xmlWriter.writeElementString("ORDERID","");
                    /*缴费类型 01:上海车险 02 :非上海车险*/
                    String payinfo = "01";
                    tmpXml.writeElementString("PAYINFO", payinfo);
                    xmlWriter.writeElementString("PAYINFO", payinfo);
                    /*交易提交时间 yyyyMMddhhmmss*/
                    tmpXml.writeElementString("TRADETIME", Format.DateTime14Format.format(p_req9110.singleDetail.getPayDateTime()));
                    xmlWriter.writeElementString("TRADETIME", Format.DateTime14Format.format(p_req9110.singleDetail.getPayDateTime()));
                    /*短信接收手机号码*/
                    tmpXml.writeElementString("MOBILENO", p_req9110.singleDetail.cellPhone);
                    xmlWriter.writeElementString("MOBILENO", p_req9110.singleDetail.cellPhone);
                    /*短信参数*/
                    String transAmt = p_req9110.singleDetail.payAmount;
                    /*如果是上海车险 交易金额单位为元 如果非上海车险交易金额单位为分*/
                    if ("02".equals(payinfo)) {
                        transAmt = StringHelper.amountMultiply100(transAmt);
                    }
                    /*参数格式 姓名|证件号码|银行卡号|交易金额*/
                    String smsParam = p_req9110.singleDetail.payName + "|" + p_req9110.singleDetail.certNum + "|" + p_req9110.singleDetail.payAct + "|" + transAmt;
                    tmpXml.writeElementString("SMSPARAM", smsParam);
                    xmlWriter.writeElementString("SMSPARAM", smsParam);
                    /*签名及计算长度*/
                    tmpXml.writeEndDocument();
                    /*长度计算不包括 MAC 值。长度位数不足左补0*/
                    String workKey = actItem.saltKey;
                    String mac = Util.xorAndGenMac(tmpXml.toXmlString(), workKey);
                    WriteBankLogLn("发送银行原始报文\r\n" + tmpXml);
                    xmlWriter.writeElementString("MAC", mac);
                    xmlWriter.writeEndDocument();
                    String lengthStr = Integer.toHexString(tmpXml.toXmlString().length());
                    lengthStr = "0000".substring(0, 4 - lengthStr.length()) + lengthStr;
                    String tmpStr = lengthStr.toUpperCase() + xmlWriter.toXmlString();
                    String[] tmpStrRet = sendToBank(tmpStr, bankFront.getUrl("smsRecSubmit"));
                    if (tmpStrRet[0].length() == 0) {
                        StringBuilder tmpSbMsg = new StringBuilder();
                        // 解析银行返回
                        XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                        if (tmpBkReader != null) {
                            String busCode = tmpBkReader.getFirstText("/MESSAGE/MBODY/BUSINCODE");
                            String rtncode = tmpBkReader.getFirstText("/MESSAGE/MBODY/RTNCODE");
                            if (verifySignByRSA(tmpStrRet[1], actItem.saltKey)) {
                                if ("OK".equals(rtncode)) {
                                    if (ZBF01TransType.SMSSTEP1.equals(busCode)) {
                                        tmpRetDetail.respCode = "0";
                                        tmpRetDetail.respInfo = "通讯成功";
                                        tmpRetDetail.respInfo = "已提交";
                                        tmpRetDetail.transState = PaymentState.SUCCESS;
                                        tmpRetDetail.payInfoCode = rtncode;
                                    } else {
                                        tmpRetDetail.respCode = "-1";
                                        tmpRetDetail.respInfo = "银行返回报文交易类型错误:" + busCode;
                                    }
                                } else if ("ER".equals(rtncode)) {
                                    String erMsg = tmpBkReader.getFirstText("/MESSAGE/MBODY/RTNMSG");
                                    tmpRetDetail.respCode = "0";
                                    tmpRetDetail.respInfo = erMsg;
                                }
                            } else {
                                tmpRetDetail.respCode = "-1";
                                tmpRetDetail.respInfo = "签名验证失败";
                            }
                        } else {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = tmpSbMsg.toString();
                        }

                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = tmpStrRet[1];
                    }

                } else if ("02".equals(p_req9110.singleDetail.step)) {
                    /*签名及计算长度用xml*/
                    XmlTextWriter tmpXml = new XmlTextWriter();
                    /*发送银行用xml*/
                    XmlTextWriter xmlWriter = new XmlTextWriter();
                    writeCommonHeaderVer1(tmpXml, "1");
                    writeCommonHeaderVer1(xmlWriter, "1");
                    /*业务代码*/
                    tmpXml.writeElementString("BUSINCODE", ZBF01TransType.UNIFINEDORDER);
                    xmlWriter.writeElementString("BUSINCODE", ZBF01TransType.UNIFINEDORDER);
                    /*商户号*/
                    tmpXml.writeElementString("MERCHANTID", mchId);
                    xmlWriter.writeElementString("MERCHANTID", mchId);

                    /*是否批量支付*/
                    tmpXml.writeElementString("IS_BATCH", "0");
                    xmlWriter.writeElementString("IS_BATCH", "0");

                    /*支付号  当【IS_BATCH】为【0：单笔支付】，填入支付号*/

                    /*支付号?????*/
                    tmpXml.writeElementString("POLICYID", "");
                    xmlWriter.writeElementString("POLICYID", "");

                    /*校验码  如果有则填入，没有可为空；*/
//                    tmpXml.writeElementString("VERIFICACODE", );
//                    xmlWriter.writeElementString("VERIFICACODE", );

                    /*01：上海车险02：非法输入，请求会被拒绝 03：非上海车险或非车险*/
                    String payinfo = "01";

                    tmpXml.writeElementString("PAYINFO", payinfo);
                    xmlWriter.writeElementString("PAYINFO", payinfo);

                    /*商户流水号  商户系统交易流水号，由商户生成*/
                    tmpXml.writeElementString("BIZNO", p_req9110.singleDetail.askNumber);
                    xmlWriter.writeElementString("BIZNO", p_req9110.singleDetail.askNumber);

                    /*金额  单位:分*/
                    String amount = StringHelper.amountMultiply100(p_req9110.singleDetail.payAmount);
                    tmpXml.writeElementString("AMOUNT", amount);
                    xmlWriter.writeElementString("AMOUNT", amount);

                    /*订单有效时间  单位：分钟最短 5 分钟，最长 120 分钟，如果不填写默认为 120 分钟 */
                    tmpXml.writeElementString("VALIDTIME", "5");
                    xmlWriter.writeElementString("VALIDTIME", "5");

                    XmlTextWriter goodslist = new XmlTextWriter();
                    goodslist.writeStartElement("GOODS");
                    /*支付号*/
                    goodslist.writeElementString("POLICYID", "");
                    /*保单号*/
                    goodslist.writeElementString("GOODSID", p_req9110.singleDetail.policyNumber);
                    /*保单金额*/
                    goodslist.writeElementString("GOODSAMT", amount);
                    goodslist.writeEndDocument();
                    /*保单号列表*/
                    xmlWriter.writeElementString("GOODSLIST", goodslist.toXmlString());

                    /*交易日期  yyyyMMdd*/
                    String paydatetime = Format.DateTime14Format.format(p_req9110.singleDetail.getPayDateTime());
                    tmpXml.writeElementString("TRADE_DATE", paydatetime.substring(0, 8));
                    xmlWriter.writeElementString("TRADE_DATE", paydatetime.substring(0, 8));
                    /*交易时间 hhmmss*/
                    tmpXml.writeElementString("TRADE_TIME", paydatetime.substring(8, 14));
                    xmlWriter.writeElementString("TRADE_TIME", paydatetime.substring(8, 14));
                    /*收银台通道编码 . 收银台通道编码表
                            WECHAT 微信
                            PAYECO 易联
                            CHANPAY 畅捷
                            ONECODE 一码付
                            BAOFOO 宝付 */
                    tmpXml.writeElementString("PAY_PRODUCT", "PAYECO");
                    xmlWriter.writeElementString("PAY_PRODUCT", "PAYECO");
                    /*支付产品编码  JSAPI 		微信微信支付
                                            NATIVE		微信扫码支付
                                            QUICK		快捷支付
                                            C_JSAPIWX	微信支付
                                            C_SCANWX    微信扫码
                                            C_SCANAL    支付宝扫码
                                            C_WAPALI    支付宝WAP支付
                                            C_WXH5 	    微信H5支付
                                            C_WXMINI    微信小程序
                                            ONECODE	    一码付扫码
                                            INSTALLMENT 信用卡分期*/
                    tmpXml.writeElementString("CHANNELS", "QUICK");
                    xmlWriter.writeElementString("CHANNELS", "QUICK");
                    XmlTextWriter channelsInfo = new XmlTextWriter();
                    /*短信凭证号 通过【 3.4 短信验证码获取（CDM1705001）】接口返回*/
                    channelsInfo.writeElementString("SMSID", p_req9110.singleDetail.verifyCode);
                    /*姓名*/
                    channelsInfo.writeElementString("NAME", p_req9110.singleDetail.payName);
                    /*银行卡号*/
                    channelsInfo.writeElementString("BANKCARD", p_req9110.singleDetail.payAct);
                    /*手机号  支付银行卡绑定手机号*/
                    channelsInfo.writeElementString("MOBILENO", p_req9110.singleDetail.cellPhone);
                    /*身份证件号*/
                    channelsInfo.writeElementString("IDCARD", p_req9110.singleDetail.certNum);
                    channelsInfo.writeEndDocument();

                    /*支付信息*/
                    tmpXml.writeElementString("CHANNELS_INFO", channelsInfo.toXmlString());
                    xmlWriter.writeElementString("CHANNELS_INFO", channelsInfo.toXmlString());

                    /*通知结果 URL   接收支付结果通知 URL*/
                    tmpXml.writeElementString("NOTIFY_URL", actItem.notifyURL);
                    xmlWriter.writeElementString("NOTIFY_URL", actItem.notifyURL);
                    /*页面跳转同步返回页面路径   处理完请求后，当前页面自动跳转到商户网站里指定页面的http 路径。空则不会进行该操作*/
                    tmpXml.writeElementString("RETURN_URL", actItem.returnURL);
                    xmlWriter.writeElementString("RETURN_URL", actItem.returnURL);

                    /*实名认证方式  04：上海模式 05：全国模式*/
                    tmpXml.writeElementString("REALNAMEMODE", "04");
                    xmlWriter.writeElementString("REALNAMEMODE", "04");
                    /*证件类型*/
                    tmpXml.writeElementString("CERTTYPE", convertCertTypeToBank(p_req9110.singleDetail.certType));
                    xmlWriter.writeElementString("CERTTYPE", convertCertTypeToBank(p_req9110.singleDetail.certType));
                    /*证件号码 投保人证件号（实名验证用） */
                    tmpXml.writeElementString("CERTNO", p_req9110.singleDetail.certNum);
                    xmlWriter.writeElementString("CERTNO", p_req9110.singleDetail.certNum);
                    /*投保人姓名（实名验证用）*/
                    tmpXml.writeElementString("PERSONNAME", p_req9110.singleDetail.payName);
                    xmlWriter.writeElementString("PERSONNAME", p_req9110.singleDetail.payName);
                    /*手机号  投保人手机号*/
                    tmpXml.writeElementString("PHONE", p_req9110.singleDetail.cellPhone);
                    xmlWriter.writeElementString("PHONE", p_req9110.singleDetail.cellPhone);
                    /*说明*/
                    tmpXml.writeElementString("REMARK", p_req9110.singleDetail.attach);
                    xmlWriter.writeElementString("REMARK", p_req9110.singleDetail.attach);
                    tmpXml.writeEndDocument();
                    int length = tmpXml.toXmlString().length();
                    WriteBankLogLn("发送银行原始报文\r\n" + tmpXml);
                    /*长度计算不包括 MAC 值。长度位数不足左补0*/
                    String mac = Util.xorAndGenMac(tmpXml.toXmlString(), actItem.saltKey);
                    xmlWriter.writeElementString("MAC", mac);
                    xmlWriter.writeEndDocument();
                    String lengthStr = Integer.toHexString(tmpXml.toXmlString().length());
                    lengthStr = "0000".substring(0, 4 - lengthStr.length()) + lengthStr;
                    String tmpStr = lengthStr.toUpperCase() + xmlWriter.toXmlString();
                    String[] tmpStrRet = sendToBank(tmpStr, bankFront.getUrl("smsRecSubmit"));
                    if (tmpStrRet[0].length() == 0) {
                        StringBuilder tmpSbMsg = new StringBuilder();
                        // 解析银行返回
                        XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                        if (tmpBkReader != null) {
                            String busCode = tmpBkReader.getFirstText("/MESSAGE/MBODY/BUSINCODE");
                            String rtncode = tmpBkReader.getFirstText("/MESSAGE/MBODY/RTNCODE");
                            if (verifySignByRSA(tmpStrRet[1], actItem.saltKey)) {
                                if ("OK".equals(rtncode)) {
                                    if (ZBF01TransType.UNIFINEDORDER.equals(busCode)) {
                                        // 有最终状态才更新支付提交状态
                                        tmpRetDetail.transState = rtncode;
                                        /*订单号*/
                                        String outTransID = tmpBkReader.getFirstText("/MESSAGE/MBODY/ORDERID");
                                        tmpRetDetail.outTransID = outTransID;
                                        String reqSeqID = tmpBkReader.getFirstText("/MESSAGE/MBODY/BIZNO");
                                        if (tmpRetDetail.reqSeqID.equals(reqSeqID)) {
                                            String transAmount = tmpBkReader.getFirstText("/MESSAGE/MBODY/AMOUNT");
                                            tmpRetDetail.transAmt = StringHelper.amountDivide100(transAmount);
                                        } else {
                                            tmpRetDetail.respCode = "-1";
                                            tmpRetDetail.respInfo = "返回流水号与请求流水号不一致";
                                            WriteBankLogLn("返回流水号与请求流水号不一致:\r\n" + "请求流水号:" + tmpRetDetail.reqSeqID + "\r\n" + "返回流水号:" + reqSeqID);
                                        }
                                    } else {
                                        tmpRetDetail.respCode = "-1";
                                        tmpRetDetail.respInfo = "银行返回报文交易类型错误:" + busCode;
                                        WriteBankLogLn(tmpRetDetail.respInfo);
                                    }

                                } else {
                                    String errMsg = tmpBkReader.getFirstText("/MESSAGE/MBODY/RTNMSG");
                                    tmpRetDetail.respCode = "0";
                                    tmpRetDetail.respInfo = errMsg;
                                    tmpRetDetail.transState = rtncode;
                                }
                            } else {
                                tmpRetDetail.respCode = "-1";
                                tmpRetDetail.respInfo = "签名验证失败";
                                WriteBankLogLn("签名验证失败:" + actItem.saltKey);
                            }


                        } else {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = tmpSbMsg.toString();
                        }

                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = tmpStrRet[1];
                    }
                } else {
                    tmpRetDetail.respCode = "0";
                    tmpRetDetail.respInfo = "未能识别的step：" + p_req9110.singleDetail.step;
                    tmpRetDetail.transState = PaymentState.FAIL_Payment;
                    tmpRetDetail.payInfoCode = FailCode.E9981;
                }
            } else {
                tmpRetDetail.respCode = "0";
                tmpRetDetail.respInfo = "未找到账号[" + p_req9110.singleDetail.recAct + "]商户配置信息!";
                tmpRetDetail.transState = PaymentState.FAIL_Payment;
                tmpRetDetail.payInfoCode = FailCode.E9981;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }


    @Override
    public RetAtsSingle d_9146_QrySMSRec(ReqQrySingle p_req9146) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req9146.reqHeader);
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
        tmpRetDetail.reqSeqID = p_req9146.askNumber;

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_req9146.recAct, "smsRec");
            if (actItem != null) {
                String mchId = actItem.merchantId;
                /*发送银行用xml*/
                XmlTextWriter xmlWriter = new XmlTextWriter();
                writeCommonQryXml(xmlWriter, mchId, p_req9146.reqHeader.transSeqID, ZBF01TransType.COMMONQRY, p_req9146.askNumber);
                /*查询提交时间*/
                String mac = Util.xorAndGenMac(xmlWriter.toXmlString(), actItem.saltKey);
                /*拼接长度*/
                String lengthStr = Integer.toHexString(xmlWriter.toXmlString().length());
                lengthStr = "0000".substring(0, 4 - lengthStr.length()) + lengthStr;
                String tmpStr = lengthStr.toUpperCase() + xmlWriter.toXmlString();
                /*拼接MAC*/
                String sendMsg = tmpStr + mac;
                String[] tmpStrRet = sendToBank(sendMsg, bankFront.getUrl("qryUrl"));
                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    // 解析银行返回
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String busCode = tmpBkReader.getFirstText("/MHEAD/PROCCODE");
                        if (ZBF01TransType.COMMONQRY.equals(busCode)) {
                            String rtncode = tmpBkReader.getFirstText("/MESSAGE/MBODY/RTNCODE");
                            String retMac = tmpStrRet[1].substring(tmpStrRet[1].lastIndexOf(">")+1);
                             mac = Util.xorAndGenMac(tmpStrRet[1].substring(0,tmpStrRet[1].lastIndexOf(">")+1), actItem.saltKey);
                            if (mac.equals(retMac)) {
                                if ("00".equals(rtncode)) {
                                    tmpRetDetail.respCode = "0";
                                    String status = tmpBkReader.getFirstText("/MESSAGE/MBODY/POLICYSTATUS");
                                    tmpRetDetail.transState = rtncode + "+" + status;
                                    /*???要返回什么*/
                                    String transAmt = tmpBkReader.getFirstText("/MESSAGE/MBODY/AMT");
                                    tmpRetDetail.transAmt = StringHelper.amountDivide100(transAmt);
                                    //中保付流水号
                                    String outTransSeq = tmpBkReader.getFirstText("/MESSAGE/MBODY/SERIALNUMBER");
                                    tmpRetDetail.outTransID = outTransSeq;
                                    tmpRetDetail.payInfoCode = tmpRetDetail.transState;
                                    String retMsg = "";
                                    if ("1".equals(status)) {
                                        retMsg = "成功支付";
                                    } else if ("0".equals(status)) {
                                        retMsg = "无成功支付记录";
                                    }
                                    tmpRetDetail.respInfo = retMsg;
                                } else {
                                    String errMsg = tmpBkReader.getFirstText("/MESSAGE/MBODY/ERRMSG");
                                    tmpRetDetail.respCode = "0";
                                    tmpRetDetail.respInfo = errMsg;
                                    tmpRetDetail.payInfoCode = errMsg;
                                    tmpRetDetail.transState = rtncode;
                                }
                            } else {
                                tmpRetDetail.respCode = "-1";
                                tmpRetDetail.respInfo = "签名验证失败";
                                WriteBankLogLn("签名验证失败:" + actItem.saltKey);
                            }
                        } else {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = "银行返回报文交易类型错误:" + busCode;
                            WriteBankLogLn(tmpRetDetail.respInfo);
                        }
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = tmpSbMsg.toString();
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpStrRet[1];
                }
            } else {
                tmpRetDetail.respCode = "0";
                tmpRetDetail.respInfo = "未找到账号[" + p_req9146.recAct + "]商户配置信息!";
                tmpRetDetail.transState = PaymentState.FAIL_Payment;
                tmpRetDetail.payInfoCode = FailCode.E9981;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }


}

